//@author A0091838U
package crossoff.datetime;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;

import org.joda.time.DateTime;
import org.junit.Test;

public class DateTimeHandlerTest {

	Time24HoursValidator TV24 = new Time24HoursValidator();
	Time12HoursValidator TV12 = new Time12HoursValidator();
	DateValidator DV = new DateValidator();
	DateTimeHandler DTHD = new DateTimeHandler();

	@Test
	/* This is a boundary case for the '24hours boundary' partition */
	public void test24HoursFormatCase1() throws IOException {
		assertTrue(TV24.validate("23:59"));
		;
	}

	@Test
	public void testHoursFormatCase2() throws IOException {
		String[] commandSplit = { "aaa", "23:59", "bbb" };
		assertEquals("23:59:00.000", DTHD.evaluateTimeStr(commandSplit, 1)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the '24hours boundary' partition */
	public void test24HoursFormatCase3() throws IOException {
		assertFalse(TV24.validate("24:00"));
	}

	@Test
	public void test24HoursFormat1Case1() throws IOException {
		assertTrue(TV24.validate1("2359"));
	}

	@Test
	public void test24HoursFormat1Case2() throws IOException {
		String[] commandSplit = { "a", "b", "c", "2359" };
		assertEquals("23:59:00.000", DTHD.evaluateTimeStr(commandSplit, 3)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the '12hours boundary' partition */
	public void test12HoursFormatCase1() throws IOException {
		assertTrue(TV12.validate("12:59 am"));
	}

	@Test
	public void test12HoursFormatCase2() throws IOException {
		String[] commandSplit = { "12:59am", "a", "b" };
		assertEquals("00:59:00.000", DTHD.evaluateTimeStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the '12hours boundary' partition */
	public void test12HoursFormatCase3() throws IOException {
		assertFalse(TV12.validate("13:00pm"));
	}

	@Test
	public void test12HoursFormat1Case1() throws IOException {
		String[] commandSplit = { "1259 pm", "aaa" };
		assertEquals("12:59:00.000", DTHD.evaluateTimeStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	public void test12HoursFormat2Case1() throws IOException {
		assertTrue(TV12.validate1("8pm"));
	}

	@Test
	public void test12HoursFormat2Case2() throws IOException {
		String[] commandSplit = { "8 pm" };
		assertEquals("20:00:00.000", DTHD.evaluateTimeStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	public void test12HoursFormat3Case1() throws IOException {
		String[] commandSplit = { "10" };
		assertEquals("10:00:00.000", DTHD.evaluateTimeStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the 'February' partition */
	public void testDateFormat0() throws IOException {
		assertTrue(DV.validate("28/2/2013"));
	}

	@Test
	public void testDateFormat1() throws IOException {
		String[] commandSplit = { "28-2-2013" };
		assertEquals("2013-02-28", DTHD.evaluateDateStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the 'February' partition */
	public void testDateFormat2() throws IOException {
		assertFalse(DV.validate2("29/2/13"));
	}

	@Test
	/* This is a boundary case for the 'October' partition */
	public void testDateFormat3() throws IOException {
		assertTrue(DV.validate3("30-12-13"));
	}

	@Test
	public void testDateFormat4() throws IOException {
		String[] commandSplit = { "31-8" };
		assertEquals("2014-08-31", DTHD.evaluateDateStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	/* This is a boundary case for the 'March' partition */
	public void testDateFormat5() throws IOException {
		assertFalse(DV.validate5("32-3"));
	}

	@Test
	public void testDateFormat6() throws IOException {
		assertTrue(DV.validate6("29 Feb 16"));
	}

	@Test
	public void testDateFormat11() throws IOException {
		assertTrue(DV.validate11("29 Nov 2012"));
	}

	@Test
	public void testDateFormat14() throws IOException {
		assertFalse(DV.validate14("31.Nov"));
	}

	@Test
	public void testDateFormat15() throws IOException {
		String[] commandSplit = { "31", "Mar" };
		assertEquals("2014-03-31", DTHD.evaluateDateStr(commandSplit, 0)
				.getFirst().toString());
	}

	@Test
	public void testConvertDateTimeStrCase1() throws IOException {
		String[] commandSplit = { "8am", "31", "Mar" };
		DateTime dt = new DateTime(2014, 3, 31, 8, 0);
		assertTrue(DTHD.evaluateDateTimeStr(commandSplit, 0).getFirst()
				.equals(dt));
	}

	@Test
	public void testConvertDateTimeStrCase2() throws IOException {
		String[] commandSplit = { "8", "pm", "28", "Feb" };
		DateTime dt = new DateTime(2014, 2, 28, 20, 0);
		assertTrue(DTHD.evaluateDateTimeStr(commandSplit, 0).getFirst()
				.equals(dt));
	}

	@Test
	public void testConvertDateTimeStrCase3() throws IOException {
		String[] commandSplit = { "8", "pm", "29", "Feb", "2016" };
		DateTime dt = new DateTime(2016, 2, 29, 20, 0);
		assertTrue(DTHD.evaluateDateTimeStr(commandSplit, 0).getFirst()
				.equals(dt));
	}

	@Test
	public void testConvertDateTimeStrCase4() throws IOException {
		String[] commandSplit = { "0859", "31-12-2024" };
		DateTime dt = new DateTime(2024, 12, 31, 8, 59);
		assertTrue(DTHD.evaluateDateTimeStr(commandSplit, 0).getFirst()
				.equals(dt));
	}
}